package com.wf.classRoomTest.customer;

import java.util.LinkedList;

public class ProducerConsumerExample {
    public static void main(String[] args) {
        LinkedList<Integer> sharedList = new LinkedList<>();
        Thread producer = new Thread(new Producer(sharedList), "Producer");
        Thread consumer = new Thread(new Consumer(sharedList), "Consumer1");
        Thread consumer1 = new Thread(new Consumer(sharedList), "Consumer2");
        Thread consumer2 = new Thread(new Consumer(sharedList), "Consumer3");
        Thread consumer3 = new Thread(new Consumer(sharedList), "Consumer4");

        producer.start();
        consumer.start();
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }

    static class Producer implements Runnable {
        private final LinkedList<Integer> sharedList;
        private final int MAX_SIZE = 10;
        private int value = 1;

        Producer(LinkedList<Integer> sharedList) {
            this.sharedList = sharedList;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    produce(value++);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 生产者方法，用于向共享列表中添加元素。
         * 当共享列表已满时，生产者线程将等待，直到消费者线程释放资源。
         *
         * @param value 要生产并添加到共享列表的值。
         * @throws InterruptedException 如果线程在等待时被中断。
         */
        void produce(int value) throws InterruptedException {
            synchronized (sharedList) {
                // 当共享列表已满时，等待消费者释放资源。
                while (sharedList.size() == MAX_SIZE) {
                    System.out.println("生产队列已满！等待消费");
                    sharedList.wait();
                }

                System.out.println("生产: " + value);
                sharedList.add(value);

                // 模拟生产过程，让线程休眠1秒。
                Thread.sleep(1000);

                // 唤醒所有等待的消费者线程，让他们可以继续消费。
                sharedList.notifyAll();
            }
        }
    }

    static class Consumer implements Runnable {
        private final LinkedList<Integer> sharedList;

        Consumer(LinkedList<Integer> sharedList) {
            this.sharedList = sharedList;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        void consume() throws InterruptedException {
            synchronized (sharedList) {
                while (sharedList.isEmpty()) {
                    System.out.println(Thread.currentThread().getName()+"生产桌子上为空！等待生产");
                    sharedList.wait();
                }
                int value = sharedList.poll();
                System.out.println(Thread.currentThread().getName() +"--->"+ value);
                Thread.sleep(1000); // 模拟消费过程
                sharedList.notifyAll();
            }
        }
    }
}
